﻿using Newtonsoft.Json.Serialization;
using RuoVea.ExFilter;
using RuoVea.ExSugar;
using RuoVea.Iot.MqttClient.Server;
using RuoVea.OmiDict;
using RuoVea.OmiLog;
using SqlSugar;

namespace RuoVea.Iot.MqttClient;

/// <summary>
/// 
/// </summary>
public class Program
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    public static async Task Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Configuration.AddEnvironmentVariables();
        // Add services to the container.

        builder.Services.AddControllers()
            .AddNewtonsoftJson(options =>
            {
                //不使用驼峰命名样式
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                //设置时间格式
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            });

        builder.Services
            .AddOmiDictSetup()
            .AddOmiLogSetup();

        builder.Services
            .AddSqlSugarSetup();

        // 注册配置
        builder.Services.Configure<MqttOptions>(builder.Configuration.GetSection("MqttClientInfo"));
        // 注册 MQTT 服务
        builder.Services.AddSingleton<MqttClientService>();
        // 注册后台服务
        builder.Services.AddHostedService<MqttBackgroundService>();

        builder.Services
            .AddDictInitSetup()
            .AddLogInitSetup();/*需要在 AddSqlSugarSetup之后*/

        builder.Services
            .RequestActionSetup() // 注入 请求日志拦截 [执行操作日志、参数验证 ]
            .ResultSetup()
            .ExceptionSetup();

        var app = builder.Build();

        // 显式启动 MQTT 服务
        var mqttService = app.Services.GetRequiredService<MqttClientService>();
        await mqttService.MqttClientStart();

        app.UseOmiLogUI();
        app.UseOmiDictUI();

        app.MapControllers();

        // 初始化数据库表
        
        {
            var _thisRepository = app.Services.GetRequiredService<ISqlSugarClient>();
            if (!_thisRepository.Queryable<OmiApi.Dict.Entitys.SysDictType>().Any(x => x.Code == "mqtt"))
            {
                long typeId = ExIdGen.IdGenerator.Id;
                await _thisRepository.Insertable(
                    new OmiApi.Dict.Entitys.SysDictType
                    {
                        Id = typeId,
                        CreateTime = DateTime.Now,
                        IsDelete = ExEnum.IsDelete.N,
                        IsDisable = ExEnum.YesOrNot.N,
                        Sort = 100,
                        SysFlag = ExEnum.YesOrNot.Y,
                        Code = "mqtt",
                        Name = "Mqtt配置",
                        Remark = "Mqtt配置信息"
                    }).ExecuteCommandAsync();

                var dictValues = new List<OmiApi.Dict.Entitys.SysDictValue>
                {
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "Server",
                        Label="Server",
                        Value = "127.0.0.1",
                        Remark = "Mqtt地址:broker-cn.emqx.io"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "Port",
                        Label="Port",
                        Value = "1883",
                        Remark = "Port"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "UserName",
                        Label="UserName",
                        Value = "admin",
                        Remark = "UserName"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "Password",
                        Label="Password",
                        Value = "123456",
                        Remark = "Password"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "ClientIdPrefix",
                        Label="ClientIdPrefix",
                        Value = "RuoVeaClient_",
                        Remark = "ClientIdPrefix"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "MaxPayloadSize",
                        Label="MaxPayloadSize",
                        Value = "256",
                        Remark = "最大限制/字节"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "TopicPrefix",
                        Label="TopicPrefix",
                        Value = "app/ruovea/client",
                        Remark = "TopicPrefix"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "DefaultPublishTopic",
                        Label="DefaultPublishTopic",
                        Value = "publish",
                        Remark = "DefaultPublishTopic"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "DefaultSubscribeTopics",
                        Label="DefaultSubscribeTopics",
                        Value = "subscribe",
                        Remark = "DefaultSubscribeTopics"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "DefaultQoS",
                        Label="DefaultQoS",
                        Value = "1",
                        Remark = "默认主题的 QoS 级别"
                    },
                    new OmiApi.Dict.Entitys.SysDictValue
                    {
                        Id=ExIdGen.IdGenerator.Id, CreateTime = DateTime.Now, IsDelete = ExEnum.IsDelete.N, IsDisable = ExEnum.YesOrNot.N, Sort = 100, TypeId=typeId,TagType="info",
                        Code = "HeartbeatInterval",
                        Label="HeartbeatInterval",
                        Value = "60",
                        Remark = "心跳配置 秒"
                    }
                };
                await _thisRepository.Insertable(dictValues).ExecuteCommandAsync();
            }
        };

        app.Run();
    }
}
